/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package sixsigma;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;

import java.io.InputStream;
import java.sql.*;
import java.util.Vector;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;

/**
 *
 * @author Marc
 */
public class DbKomm
{
	String jdbcDriver;
	String jdbcurl;
	String user;
	String pw;

	Connection con;
	Statement stmt;

        /**
         * Gibt die aktuelle JDBC-MySQL-Connection zurück
         * @return con
         */
        public Connection getConnection(){
        try {
            open();
        } catch (Exception ex) {
            Logger.getLogger(DbKomm.class.getName()).log(Level.SEVERE, null, ex);
        }
            return con;
        }

        /**
         * Erzeugt eine Instanz der DBKomm-Klasse und setzt Verbindungsdaten fest.
         */
        public DbKomm()
	{
		this.jdbcurl = "jdbc:mysql://localhost:3306/sixsigma";
		this.jdbcDriver = "com.mysql.jdbc.Driver";
		this.user = "root";
		this.pw = "";
	}

        /**
         * Öffnet eine Datenbankverbindung
         * @return con.isClosed()
         * @throws Exception
         */
        public boolean open() throws Exception
	{
            Class.forName(jdbcDriver).newInstance(); //Initialisierung des Datenbanktreibers
            con=DriverManager.getConnection(jdbcurl,user,pw); //Aufbau der Datenbankverbindung
            return con.isClosed();
	}

        /**
         * Schließt die Datenbankverbindung.
         * @return con.isClosed()
         * @throws Exception
         */
        public boolean close() throws Exception
	{
		con.close();
		return con.isClosed();
	}

        /**
         * Führt einen SQL-Befehl aus. Am besten geeignet für Inserts und Updates
         * @param insert_text
         */
        public void execute(String insert_text)
	{
		try
		{
			stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
			stmt.execute(insert_text);
			stmt.close();
		}
		catch(SQLException sqlE)
		{
			System.err.println(sqlE.getMessage());
		}
		catch(Exception e)
		{
			System.err.println(e.getMessage());
		}
	}

        /**
         * Ließt ein Ergebnis des übergebenen SQL-Befehles aus und gibt diesen Zurück.
         * @param SQL
         * @return abfrage_ergebnis
         */
        public String[][] einfachArrayAuslesen(String SQL)
	{
		String[][] abfrage_ergebnis = {};
		try
		{
			stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
			ResultSet rs1 = stmt.executeQuery(SQL);
			rs1.last();
			int mng_datensaetze = rs1.getRow();
			int mng_col = rs1.getMetaData().getColumnCount();
			abfrage_ergebnis = new String[mng_datensaetze][mng_col];
			rs1.beforeFirst();

			while(rs1.next())
			{
				for(int i=1;i<=mng_col;i++)
				{
					abfrage_ergebnis[rs1.getRow()-1][i-1] = rs1.getString(i);
				}
			}
			rs1.close();
			stmt.close();
		}
		catch(SQLException sqlE)
		{}
		return abfrage_ergebnis;
	}

        /**
         * Gibt ein Bild aus der Datenbank als Byte-Array zurück.
         * @param SQL
         * @param output
         * @return bytes
         */
        public byte[] getImage(String SQL){
            String[]        ss;
            BufferedImage[] imgs;
            byte[] bytes = null;


            Vector vStr = new Vector();
            Vector vImg = new Vector();
            Connection cn = null;
            Statement st = null;
            ResultSet rs = null;
            try {
                cn = getConnection();
                st = cn.createStatement();
                rs = st.executeQuery(SQL);
                while( rs.next() ) {
                    InputStream is = rs.getBinaryStream("IMAGE");
                    bytes = rs.getBytes("IMAGE");
                    if( null != is ) {
                        vStr.add( rs.getString( 1  ) );
                        vImg.add( ImageIO.read( is ) );
                        try { is.close(); } catch( Exception ex ) {}
                    }
                }
            } catch( Exception ex ) {
                System.out.println( ex );
            } finally {
                try { if( null != rs ) rs.close(); } catch( Exception ex ) {}
                try { if( null != st ) st.close(); } catch( Exception ex ) {}
                try { if( null != cn ) cn.close(); } catch( Exception ex ) {}
            }
            ss   = (String[])(vStr.toArray( new String[vStr.size()] ));
            imgs = (BufferedImage[])(vImg.toArray( new BufferedImage[vImg.size()] ));

            return bytes;
        }

        /**
         * Fügt ein Bild in die Datenbank ein.
         * @param img
         * @param inhalt
         * @param SQL
         */
        public void insertImage(File img, String inhalt, String SQL){
            Connection connection = getConnection();
            /* prepareStatement() is used for create statement object that is
            used for sending sql statements to the specified database. */
            PreparedStatement psmnt = null;
            try {
            psmnt = connection.prepareStatement(SQL);
            psmnt.setString(1,inhalt);
            FileInputStream fis = new FileInputStream(img);
            psmnt.setBinaryStream(2, (InputStream)fis, (int)(img.length()));
            /* executeUpdate() method execute specified sql query. Here this query
            insert data and image from specified address. */
            int s = psmnt.executeUpdate();
            if(s>0) {
                //System.out.println("Uploaded successfully !");
            }else {
                //System.out.println("unsucessfull to upload image.");
            }
            connection.close();
            psmnt.close();
            } catch (SQLException ex) {
                Logger.getLogger(DbKomm.class.getName()).log(Level.SEVERE, null, ex);
            } catch (FileNotFoundException fex) {
                Logger.getLogger(DbKomm.class.getName()).log(Level.SEVERE, null, fex);
            }
        }

        /**
         * Aktualisiert ein vorhandenes Bild in der Datenbank.
         * @param img
         * @param inhalt
         * @param SQL
         */
        public void updateImage(File img, String inhalt, String SQL){
            Connection connection = getConnection();
            /* prepareStatement() is used for create statement object that is
            used for sending sql statements to the specified database. */
            PreparedStatement psmnt = null;
            try {
            psmnt = connection.prepareStatement(SQL);
            FileInputStream fis = new FileInputStream(img);
            psmnt.setBinaryStream(1, (InputStream)fis, (int)(img.length()));
            /* executeUpdate() method execute specified sql query. Here this query
            insert data and image from specified address. */
            int s = psmnt.executeUpdate();
            if(s>0) {
                //System.out.println("Uploaded successfully !");
            }else {
                //System.out.println("unsucessfull to upload image.");
            }
            connection.close();
            psmnt.close();
            } catch (SQLException ex) {
                Logger.getLogger(DbKomm.class.getName()).log(Level.SEVERE, null, ex);
            } catch (FileNotFoundException fex) {
                Logger.getLogger(DbKomm.class.getName()).log(Level.SEVERE, null, fex);
            }
        }



        /**
         * Nur verwendbar für Abfragen mit einem einzigen Ergebnis.
         * Gibt das Ergebnis einer SQL-Abfrage zurück, welche ein einziges
         * Ergebnis liefert. Liefert der SQL-Befehl mehrere Ergebisse,
         * wird nur das erste ausgegeben.
         * @param SQL
         * @return
         */
        public String einfacheRueckgabe(String SQL)
	{
		String[][] abfrage_ergebnis = {};
		try
		{
			stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
			ResultSet rs1 = stmt.executeQuery(SQL);
			rs1.last();
			int mng_datensaetze = rs1.getRow();
			int mng_col = rs1.getMetaData().getColumnCount();
			abfrage_ergebnis = new String[mng_datensaetze][mng_col];
			rs1.beforeFirst();

			while(rs1.next())
			{
				for(int i=1;i<=mng_col;i++)
				{
					abfrage_ergebnis[rs1.getRow()-1][i-1] = rs1.getString(i);
				}
			}
			rs1.close();
			stmt.close();
		}
		catch(SQLException sqlE)
		{}
		return abfrage_ergebnis[0][0];
	}


        /**
         * Führ einen SQL-Update Befehl aus.
         * @param insert_text
         */
        public void insert(String insert_text)
	{
		try
		{
			stmt=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
			stmt.executeUpdate(insert_text);
			stmt.close();
		}
		catch(SQLException sqlE)
		{}
		catch(Exception e)
		{}

	}

        /**
         * Setzt das Auto-Commit in der Datenbank
         * @param Schalter
         */
        public void setAutoCommit(boolean Schalter)
	{
		try
		{
			System.out.println("Setze AutoCommit auf: "+Schalter);
			con.setAutoCommit(Schalter);
			System.out.println("AutoCommit ist gesetzt auf: " + con.getAutoCommit());
		}
		catch(SQLException sqlE)
		{
			System.err.println("Fehler beim Setzen von AutoCommit:");
			System.err.println(sqlE.getMessage());
		}
	}

        /**
         * Führt einen Commit auf die Datenbank aus.
         */
        public void commit()
	{
		try
		{
			con.commit();
		}
		catch(SQLException sqlE)
		{
			System.err.println("Fehler beim Absetzen des COMMIT:");
			System.err.println(sqlE.getMessage());
		}
	}

        /**
         * Führt einen Rollback auf die Datenbank aus.
         */
        public void rollback()
	{
		try
		{
			con.rollback();
		}
		catch(SQLException sqlE)
		{
			System.err.println("Fehler beim Absetzen des ROLLBACK:");
			System.err.println(sqlE.getMessage());
		}
	}


}